<!DOCTYPE html>












  


<html class="theme-next mist use-motion" lang="zh-CN">
<head><meta name="generator" content="Hexo 3.8.0">
  <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">


  <script>
  (function(i,s,o,g,r,a,m){i["DaoVoiceObject"]=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;a.charset="utf-8";m.parentNode.insertBefore(a,m)})(window,document,"script",('https:' == document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/0f81ff2f.js","daovoice")
  daovoice('init', {
      app_id: "15fc8e87"
    });
  daovoice('update');
  </script>






  
  
    
    
  <script src="/lib/pace/pace.min.js?v=1.0.2"></script>
  <link href="/lib/pace/pace-theme-minimal.min.css?v=1.0.2" rel="stylesheet">







<meta http-equiv="Cache-Control" content="no-transform">
<meta http-equiv="Cache-Control" content="no-siteapp">






















<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">

<link href="/css/main.css?v=6.3.0" rel="stylesheet" type="text/css">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=6.3.0">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=6.3.0">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=6.3.0">


  <link rel="mask-icon" href="/images/logo.svg?v=6.3.0" color="#222">









<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Mist',
    version: '6.3.0',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":true,"scrollpercent":true,"onmobile":false},
    fancybox: false,
    fastclick: false,
    lazyload: false,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>


  




  <meta name="description" content="Integer缓存讲解，包！你！会！">
<meta name="keywords" content="Java,面试,缓存,包装类型">
<meta property="og:type" content="article">
<meta property="og:title" content="面试系列之Integer缓存所引发的惨案(保证看完你就彻底明白)">
<meta property="og:url" content="http://blog.wangxc.club/2019/08/28/1/index.html">
<meta property="og:site_name" content="冬与晨">
<meta property="og:description" content="Integer缓存讲解，包！你！会！">
<meta property="og:locale" content="zh-CN">
<meta property="og:image" content="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pLmxvbGkubmV0LzIwMTkvMDgvMjgveDlvcThLWGtMQ3dHWk5ULnBuZw?x-oss-process=image/format,png">
<meta property="og:image" content="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pLmxvbGkubmV0LzIwMTkvMDgvMjgvcnBJUmNMTVhVN29QNGxHLmpwZw?x-oss-process=image/format,png">
<meta property="og:image" content="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pLmxvbGkubmV0LzIwMTkvMDgvMjgvWVNRWFVNN0NodFpCV3VuLnBuZw?x-oss-process=image/format,png">
<meta property="og:image" content="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pLmxvbGkubmV0LzIwMTkvMDgvMjgvVGp4T0RHdzRSMTVzSWVGLnBuZw?x-oss-process=image/format,png">
<meta property="og:updated_time" content="2019-08-28T12:57:45.338Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="面试系列之Integer缓存所引发的惨案(保证看完你就彻底明白)">
<meta name="twitter:description" content="Integer缓存讲解，包！你！会！">
<meta name="twitter:image" content="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pLmxvbGkubmV0LzIwMTkvMDgvMjgveDlvcThLWGtMQ3dHWk5ULnBuZw?x-oss-process=image/format,png">






  <link rel="canonical" href="http://blog.wangxc.club/2019/08/28/1/">



<script type="text/javascript" id="page.configurations">
  CONFIG.page = {
    sidebar: "",
  };
</script>

  <title>面试系列之Integer缓存所引发的惨案(保证看完你就彻底明白) | 冬与晨</title>
  




<script async src="https://www.googletagmanager.com/gtag/js?id=UA-102769182-1"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-102769182-1');
</script>



  <script type="text/javascript">
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?809d5610fca8eaff344d9a698536110d";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
  </script>




  <noscript>
  <style type="text/css">
    .use-motion .motion-element,
    .use-motion .brand,
    .use-motion .menu-item,
    .sidebar-inner,
    .use-motion .post-block,
    .use-motion .pagination,
    .use-motion .comments,
    .use-motion .post-header,
    .use-motion .post-body,
    .use-motion .collection-title { opacity: initial; }

    .use-motion .logo,
    .use-motion .site-title,
    .use-motion .site-subtitle {
      opacity: initial;
      top: initial;
    }

    .use-motion {
      .logo-line-before i { left: initial; }
      .logo-line-after i { right: initial; }
    }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-CN">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband">
    </div>
<a href="https://github.com/vector4wang"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a>
    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">冬与晨</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
    
  </div>

  <div class="site-nav-toggle">
    <button aria-label="切换导航栏">
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>



<nav class="site-nav">
  
    <ul id="menu" class="menu">
      
        
        
        
          
          <li class="menu-item menu-item-home">
    <a href="/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-home"></i> <br>首页</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-about">
    <a href="/about/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-user"></i> <br>关于</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-tags">
    <a href="/tags/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-tags"></i> <br>标签</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-categories">
    <a href="/categories/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-th"></i> <br>分类</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-archives">
    <a href="/archives/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-archive"></i> <br>归档</a>
  </li>
        
        
        
          
          <li class="menu-item menu-item-commonweal">
    <a href="/404/" rel="section">
      <i class="menu-item-icon fa fa-fw fa-heartbeat"></i> <br>公益 404</a>
  </li>

      
      
    </ul>
  

  
    

  

  
</nav>



  



</div>
    </header>

    


    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://blog.wangxc.club/2019/08/28/1/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="wangxc">
      <meta itemprop="description" content="革命尚未成功，同志还需努力~">
      <meta itemprop="image" content="/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="冬与晨">
    </span>

    
      <header class="post-header">

        
        
          <h2 class="post-title" itemprop="name headline">面试系列之Integer缓存所引发的惨案(保证看完你就彻底明白)
              
            
          </h2>
        

        <div class="post-meta">
          <span class="post-time">

            
            
            

            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              

              
                
              

              <time title="创建时间：2019-08-28 20:52:16 / 修改时间：20:57:45" itemprop="dateCreated datePublished" datetime="2019-08-28T20:52:16+08:00">2019-08-28</time>
            

            
              

              
            
          </span>

          
            <span class="post-category">
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing"><a href="/categories/技术/" itemprop="url" rel="index"><span itemprop="name">技术</span></a></span>

                
                
              
            </span>
          

          
            
              <span class="post-comments-count">
                <span class="post-meta-divider">|</span>
                <span class="post-meta-item-icon">
                  <i class="fa fa-comment-o"></i>
                </span>
                <a href="/2019/08/28/1/#comments" itemprop="discussionUrl">
                  <span class="post-meta-item-text">评论数：</span> <span class="post-comments-count valine-comment-count" data-xid="/2019/08/28/1/" itemprop="commentCount"></span>
                </a>
              </span>
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>Integer缓存讲解，包！你！会！</p>
<a id="more"></a>

<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width="330" height="86" src="//music.163.com/outchain/player?type=2&id=204524&auto=1&height=66"></iframe>



<p>今天在整理代码的时候发现了一段程序，如下</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">Integer integer1 = <span class="number">3</span>;</span><br><span class="line">Integer integer2 = <span class="number">3</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (integer1 == integer2)</span><br><span class="line">  System.out.println(<span class="string">"integer1 == integer2"</span>);</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">  System.out.println(<span class="string">"integer1 != integer2"</span>);</span><br><span class="line"></span><br><span class="line">Integer integer3 = <span class="number">129</span>;</span><br><span class="line">Integer integer4 = <span class="number">129</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (integer3 == integer4)</span><br><span class="line">  System.out.println(<span class="string">"integer3 == integer4"</span>);</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">  System.out.println(<span class="string">"integer3 != integer4"</span>);</span><br><span class="line"></span><br><span class="line">System.out.println(Integer.valueOf(<span class="string">"127"</span>)==Integer.valueOf(<span class="string">"127"</span>));</span><br><span class="line">System.out.println(Integer.valueOf(<span class="string">"128"</span>)==Integer.valueOf(<span class="string">"128"</span>));</span><br><span class="line">System.out.println(Integer.parseInt(<span class="string">"128"</span>)==Integer.valueOf(<span class="string">"128"</span>));</span><br></pre></td></tr></table></figure>

<p>我看了一眼，只记得答案是</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">integer1 == integer2</span><br><span class="line">integer3 != integer4</span><br><span class="line">true</span><br><span class="line">false</span><br><span class="line">true</span><br></pre></td></tr></table></figure>

<p>我刚想把代码关闭，脑海里突然黑人问号？</p>
<blockquote>
<p>为什么会是这样？</p>
</blockquote>
<p>还别说，我竟然一时语噻，说不出个所以然来，考虑到这是一个面试题，而且也想去了解下设计原理，索性花了点时间去重新整理了一下，做个记录！</p>
<p>说明：本文使用的Java版本号如下</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">java version <span class="string">"1.8.0_121"</span></span><br><span class="line">Java(TM) SE Runtime Environment (build 1.8.0_121-b13)</span><br><span class="line">Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)</span><br></pre></td></tr></table></figure>

<h3 id="缓存"><a href="#缓存" class="headerlink" title="缓存"></a>缓存</h3><p>这里考察的主要是包装类型的缓存，我们点开<code>Integer</code>的源码，会发现如下代码</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">IntegerCache</span> </span>&#123;</span><br><span class="line">  <span class="comment">// 最小值</span></span><br><span class="line">  <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> low = -<span class="number">128</span>;</span><br><span class="line">  <span class="comment">// 最大值，支持自定义</span></span><br><span class="line">  <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> high;</span><br><span class="line">  <span class="comment">// 缓存数组</span></span><br><span class="line">  <span class="keyword">static</span> <span class="keyword">final</span> Integer cache[];</span><br><span class="line"></span><br><span class="line">  <span class="keyword">static</span> &#123;</span><br><span class="line">    <span class="comment">// 最大值可以通过属性配置来改变</span></span><br><span class="line">    <span class="keyword">int</span> h = <span class="number">127</span>;</span><br><span class="line">    String integerCacheHighPropValue =</span><br><span class="line">      sun.misc.VM.getSavedProperty(<span class="string">"java.lang.Integer.IntegerCache.high"</span>);</span><br><span class="line">    <span class="comment">// 如果设置了对应的属性，则使用该值</span></span><br><span class="line">    <span class="keyword">if</span> (integerCacheHighPropValue != <span class="keyword">null</span>) &#123;</span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="keyword">int</span> i = parseInt(integerCacheHighPropValue);</span><br><span class="line">        i = Math.max(i, <span class="number">127</span>);</span><br><span class="line">        <span class="comment">// 最大数组大小为Integer.MAX_VALUE</span></span><br><span class="line">        h = Math.min(i, Integer.MAX_VALUE - (-low) -<span class="number">1</span>);</span><br><span class="line">      &#125; <span class="keyword">catch</span>( NumberFormatException nfe) &#123;</span><br><span class="line">        <span class="comment">// If the property cannot be parsed into an int, ignore it.</span></span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    high = h;</span><br><span class="line">		</span><br><span class="line">    cache = <span class="keyword">new</span> Integer[(high - low) + <span class="number">1</span>];</span><br><span class="line">    <span class="keyword">int</span> j = low;</span><br><span class="line">    <span class="comment">// 将low-high范围内的值全部实例化并存入数组中当缓存使用</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> k = <span class="number">0</span>; k &lt; cache.length; k++)</span><br><span class="line">      cache[k] = <span class="keyword">new</span> Integer(j++);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// range [-128, 127] must be interned (JLS7 5.1.7)</span></span><br><span class="line">    <span class="keyword">assert</span> IntegerCache.high &gt;= <span class="number">127</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="keyword">private</span> <span class="title">IntegerCache</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这里就是<code>Integer</code>包装类型里的缓存声明:</p>
<p><code>Integer</code>第一次使用的时候就会初始化缓存，其中范围最小值为-128，最大值默认是127，它可以通过<code>-Djava.lang.Integer.IntegerCache.high=xxx</code>或者<code>-XX:AutoBoxCacheMax=xxx</code>来设置，如下图：</p>
<p><img src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pLmxvbGkubmV0LzIwMTkvMDgvMjgveDlvcThLWGtMQ3dHWk5ULnBuZw?x-oss-process=image/format,png" alt="1.png"></p>
<p><img src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pLmxvbGkubmV0LzIwMTkvMDgvMjgvcnBJUmNMTVhVN29QNGxHLmpwZw?x-oss-process=image/format,png" alt="2.jpg"></p>
<p>接着会把low至high中所有的数据初始化存入数据中，默认就是将<strong>-128~127</strong>总共256个数循环实例化存入<code>cache</code>数组中。准确的说应该是将这256个对象在内存中的地址存进数组中。</p>
<p>再来看看其他包装类型中缓存的支持；</p>
<table>
<thead>
<tr>
<th align="center">基本类型</th>
<th align="center">大小</th>
<th align="center">最小值</th>
<th align="center">最大值</th>
<th align="center">包装器类型</th>
<th align="center">缓存范围</th>
<th align="center">是否支持自定义</th>
</tr>
</thead>
<tbody><tr>
<td align="center">boolean</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center"></td>
<td align="center">Bloolean</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center">char</td>
<td align="center">6bit</td>
<td align="center">Unicode 0</td>
<td align="center">Unic ode 2(16)-1</td>
<td align="center">Character</td>
<td align="center">0~127</td>
<td align="center">否</td>
</tr>
<tr>
<td align="center">byte</td>
<td align="center">8bit</td>
<td align="center">-128</td>
<td align="center">+127</td>
<td align="center">Byte</td>
<td align="center">-128~127</td>
<td align="center">否</td>
</tr>
<tr>
<td align="center">short</td>
<td align="center">16bit</td>
<td align="center">-2(15)</td>
<td align="center">2(15)-1</td>
<td align="center">Short</td>
<td align="center">-128~127</td>
<td align="center">否</td>
</tr>
<tr>
<td align="center">int</td>
<td align="center">32bit</td>
<td align="center">-2(31)</td>
<td align="center">2(31)-1</td>
<td align="center">Integer</td>
<td align="center">-128~127</td>
<td align="center">支持</td>
</tr>
<tr>
<td align="center">long</td>
<td align="center">64bit</td>
<td align="center">-2(63)</td>
<td align="center">2(63)-1</td>
<td align="center">Long</td>
<td align="center">-128~127</td>
<td align="center">否</td>
</tr>
<tr>
<td align="center">float</td>
<td align="center">32bit</td>
<td align="center">IEEE754</td>
<td align="center">IEEE754</td>
<td align="center">Float</td>
<td align="center">-</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">double</td>
<td align="center">64bit</td>
<td align="center">IEEE754</td>
<td align="center">IEEE754</td>
<td align="center">Double</td>
<td align="center">-</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">void</td>
<td align="center">-</td>
<td align="center"></td>
<td align="center">-                        -</td>
<td align="center">Void</td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
<p>这里又来了多个黑人问号</p>
<ul>
<li>-128~127怎么来的？</li>
<li>为什么是-128 ~ 127?怎么不是-200 ~ 200呢？</li>
<li>为什么需要缓存数据？</li>
</ul>
<p>后面会讲到，我们先把程序走完~</p>
<h3 id="对象的初始化"><a href="#对象的初始化" class="headerlink" title="对象的初始化"></a>对象的初始化</h3><p>通过使用IDEA的<strong>Show ByteCode</strong>我们可以得到代码在<code>JVM</code>里的亚子，如图</p>
<p><img src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pLmxvbGkubmV0LzIwMTkvMDgvMjgvWVNRWFVNN0NodFpCV3VuLnBuZw?x-oss-process=image/format,png" alt="3.png"></p>
<p>我们可以看到<code>Integer integer1 = 3;</code> 实际上是通过<code>Integer.valueOf</code>返回一个<code>Integer</code>对象，我们再进入源码，它的最终现实如下:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Integer <span class="title">valueOf</span><span class="params">(<span class="keyword">int</span> i)</span> </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (i &gt;= IntegerCache.low &amp;&amp; i &lt;= IntegerCache.high)</span><br><span class="line">    <span class="comment">// int j = low;cache[k] = new Integer(j++);</span></span><br><span class="line">    <span class="keyword">return</span> IntegerCache.cache[i + (-IntegerCache.low)];</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> Integer(i);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>很明显了，首先判断<code>i</code>是否在已经被缓存，如果是的话直接从缓存中取出(地址)返回，否则就<strong>重新实例化</strong>一个。<br><strong>注意: 恶心的就在这里，有就从缓存拿，没有就实例化！这也就牵扯出<code>Integer Swap</code>的问题，后面文章会讲到。</strong></p>
<h3 id="对象之间的比较"><a href="#对象之间的比较" class="headerlink" title="对象之间的比较"></a>对象之间的比较</h3><h4 id><a href="#" class="headerlink" title="=="></a>==</h4><ul>
<li>基本数据类型：<code>byte</code>,<code>short</code>,<code>char</code>,<code>int</code>,<code>long</code>,<code>double</code>,<code>float</code>,<code>blooean</code>,它们之间的比较,比较是它们的值；</li>
<li>引用数据类型：使用<code>==</code>比较的时候，比较的则是它们在内存中的地址(heap上的地址)。</li>
</ul>
<h4 id="equals"><a href="#equals" class="headerlink" title="equals"></a>equals</h4><p>这个是<code>Object</code>下的一个方法，对应代码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">equals</span><span class="params">(Object obj)</span> </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> (<span class="keyword">this</span> == obj);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>默认也是比较两个对象之间的内存地址，而其他对象在继承<code>Object</code>的时候一般会去<code>Overwrite</code>此方法，所以在没有<code>Overwrite</code>的情况下用<code>equals</code>的结果跟<code>==</code>一样都是比较内存地址，否则则按照<code>Overwrite</code>规则来。</p>
<h3 id="答案分析"><a href="#答案分析" class="headerlink" title="答案分析"></a>答案分析</h3><p>再来看看本处的代码，使用<code>==</code>则认为是比较前后两者的内存地址(以下比较均使用默认的缓存大小即-128~127)</p>
<ul>
<li>第一个比较<code>integer1 == integer2</code>前后都是3，通过上述的<a href="#对象初始化">对象初始化</a>我们可以知道<code>integer1</code>和<code>integer2</code><strong>均在缓存数组</strong>中，所以<code>Integer</code>直接从缓存数组中去取出地址返回，那边显而易见的，当使用<code>==</code>的时候则为<code>true</code>;</li>
<li>第二个比较<code>integer3 == integer4</code>前后都是129，不在<strong>-128~127</strong>范围内，则<code>Integer</code>需要<strong>重新实例化</strong>，所以<code>integer3</code>和<code>integer4</code>都是重新实例化的对象，对应的地址自然而然的也就不一样了，所以结果为<code>false</code>;</li>
<li>第三和和第四个同理；</li>
<li>第五个比较 <code>Integer.parseInt(&quot;128&quot;)==Integer.valueOf(&quot;128&quot;)</code>有意思，我们先看右边，128不在缓存内需要重新实例化一个，再看左边<code>Integer.parseInt(&quot;128&quot;)</code>返回值是<code>int</code>型，最终的比较变成了<code>128==Integer(128)</code>，再看<code>ByteCode</code>,如下图，我们会发现<code>Integer(128)</code>最终使用的是<code>Integer.intValue ()</code>方法，哈哈，竟做了<strong>拆箱处理</strong>，finally，比较就变成了<code>128==128</code>,结果当然就是<code>true</code>了。</li>
</ul>
<p><img src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pLmxvbGkubmV0LzIwMTkvMDgvMjgvVGp4T0RHdzRSMTVzSWVGLnBuZw?x-oss-process=image/format,png" alt="4.png"></p>
<h3 id="扩展"><a href="#扩展" class="headerlink" title="扩展"></a>扩展</h3><p>回到第二节的两个问题：</p>
<ul>
<li>-128~127怎么来的？</li>
<li>为什么是-128 ~ 127?怎么不是-200 ~ 200呢？</li>
<li>为什么需要缓存数据？</li>
</ul>
<p>后来在网上查找，找到一个比较靠谱的<a href="https://javapapers.com/java/java-integer-cache/" target="_blank" rel="noopener">解释</a>：</p>
<blockquote>
<p>实际上，在Java 5中首次引入此功能时，范围固定为-127到+127。 后来在Java 6中，范围的最大值映射到java.lang.Integer.IntegerCache.high，VM参数允许我们设置高位数。 根据我们的应用用例，它可以灵活地调整性能。 应该从-127到127选择这个数字范围的原因应该是什么。这被认为是广泛使用的整数范围。 在程序中首次使用Integer必须花费额外的时间来缓存实例。</p>
</blockquote>
<p><a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7" target="_blank" rel="noopener">Java Language Specification</a> 的说明如下：</p>
<blockquote>
<p><em>Ideally, boxing a given primitive value</em> <code>p</code><em>, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly. For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer’s part. This would allow (but not require) sharing of some or all of these references.</em></p>
</blockquote>
<blockquote>
<p><em>This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all</em> <code>char</code> <em>and</em> <code>short</code> <em>values, as well as</em> <code>int</code> <em>and</em> <code>long</code> <em>values in the range of -32K to +32K.</em></p>
</blockquote>
<p><a href="https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#valueOf(int)" target="_blank" rel="noopener">API</a> 上解释</p>
<blockquote>
<p>Returns an Integer instance representing the specified int value. If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range</p>
</blockquote>
<p>我的理解就是：</p>
<ul>
<li>-128~127范围内的数是比较频繁使用的，JDK就增加了这一默认的范围但并不是不可变的，毕竟JDK提供了两种方法供用户自定义范围；</li>
<li>事先做缓存还是为了提高空间和时间性能！<br>(大家参照上面官方与非官方的解释，自己意会哈~)</li>
</ul>
<h3 id="附加题"><a href="#附加题" class="headerlink" title="附加题"></a>附加题</h3><p>下面的输出是什么：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Integer integer5 = <span class="keyword">new</span> Integer(<span class="number">3</span>);</span><br><span class="line">Integer integer6 = <span class="keyword">new</span> Integer(<span class="number">3</span>);</span><br><span class="line"><span class="keyword">if</span> (integer5 == integer6)</span><br><span class="line">  System.out.println(<span class="string">"integer5 == integer6"</span>);</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">  System.out.println(<span class="string">"integer5 != integer6"</span>);</span><br></pre></td></tr></table></figure>

<p>本文的示例代码: <a href="https://github.com/vector4wang/java-learning-quick/blob/master/feature-learning/src/main/java/com/feature/learn/cache/JavaIntegerCache.java" target="_blank" rel="noopener">Github</a></p>
<p>参考：</p>
<p><a href="https://stackoverflow.com/questions/20897020/why-integer-class-caching-values-in-the-range-128-to-127" target="_blank" rel="noopener">https://stackoverflow.com/questions/20897020/why-integer-class-caching-values-in-the-range-128-to-127</a></p>
<p><a href="https://stackoverflow.com/questions/20877086/why-do-comparisons-with-integer-valueofstring-give-different-results-for-12" target="_blank" rel="noopener">https://stackoverflow.com/questions/20877086/why-do-comparisons-with-integer-valueofstring-give-different-results-for-12</a></p>
<p><a href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7" target="_blank" rel="noopener">https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7</a></p>
<p><a href="https://javapapers.com/java/java-integer-cache/" target="_blank" rel="noopener">https://javapapers.com/java/java-integer-cache/</a></p>

      
    </div>

    

    
    
    

    <div>
          
            
<div class="my_post_copyright">
  <script src="//cdn.bootcss.com/clipboard.js/1.5.10/clipboard.min.js"></script>
  
  <!-- JS库 sweetalert 可修改路径 -->
  <script src="https://cdn.bootcss.com/jquery/2.0.0/jquery.min.js"></script>
  <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
  <p><span>本文标题:</span><a href="/2019/08/28/1/">面试系列之Integer缓存所引发的惨案(保证看完你就彻底明白)</a></p>
  <p><span>文章作者:</span><a href="/" title="访问 wangxc 的个人博客">wangxc</a></p>
  <p><span>发布时间:</span>2019年08月28日 - 20:08</p>
  <p><span>最后更新:</span>2019年08月28日 - 20:08</p>
  <p><span>原始链接:</span><a href="/2019/08/28/1/" title="面试系列之Integer缓存所引发的惨案(保证看完你就彻底明白)">http://blog.wangxc.club/2019/08/28/1/</a>
    <span class="copy-path" title="点击复制文章链接"><i class="fa fa-clipboard" data-clipboard-text="http://blog.wangxc.club/2019/08/28/1/" aria-label="复制成功！"></i></span>
  </p>
  <p><span>许可协议:</span><i class="fa fa-creative-commons"></i> <a rel="license" href="https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">署名-非商业性使用-禁止演绎 4.0 国际</a> 转载请保留原文链接及作者。</p>  
</div>
<script> 
    var clipboard = new Clipboard('.fa-clipboard');
    $(".fa-clipboard").click(function(){
      clipboard.on('success', function(){
        swal({   
          title: "",   
          text: '复制成功',
          icon: "success", 
          showConfirmButton: true
          });
	});
    });  
</script>

          
    </div>

    

    
      <div>
        <div style="padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;">
  <div></div>
  <button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
    <span>打赏</span>
  </button>
  <div id="QR" style="display: none;">

    
      <div id="wechat" style="display: inline-block">
        <img id="wechat_qr" src="https://i.loli.net/2017/12/29/5a4632028eaeb.jpg" alt="wangxc 微信支付">
        <p>微信支付</p>
      </div>
    

    
      <div id="alipay" style="display: inline-block">
        <img id="alipay_qr" src="https://i.loli.net/2017/12/29/5a46320234b1d.jpg" alt="wangxc 支付宝">
        <p>支付宝</p>
      </div>
    

    

  </div>
</div>

      </div>
    

    
<div>
  
    <div>
    
        <div style="text-align:center;color: #ccc;font-size:14px;">
              -------------本文结束<i class="fa fa-paw"></i>感谢您的阅读-------------
        </div>
    
</div>

  
</div>
    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/Java/" rel="tag"><i class="fa fa-tag"></i> Java</a>
          
            <a href="/tags/面试/" rel="tag"><i class="fa fa-tag"></i> 面试</a>
          
            <a href="/tags/缓存/" rel="tag"><i class="fa fa-tag"></i> 缓存</a>
          
            <a href="/tags/包装类型/" rel="tag"><i class="fa fa-tag"></i> 包装类型</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2019/07/20/1/" rel="next" title="Springboot快速教程---Docker搭建与整合Hbase">
                <i class="fa fa-chevron-left"></i> Springboot快速教程---Docker搭建与整合Hbase
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2019/09/03/1/" rel="prev" title="Mybatis中单双引号引发的惨案">
                Mybatis中单双引号引发的惨案 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          

  
    <div class="comments" id="comments">
    </div>
  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image" src="/images/avatar.jpg" alt="wangxc">
            
              <p class="site-author-name" itemprop="name">wangxc</p>
              <p class="site-description motion-element" itemprop="description">革命尚未成功，同志还需努力~</p>
          </div>

          
            <nav class="site-state motion-element">
              
                <div class="site-state-item site-state-posts">
                
                  <a href="/archives/">
                
                    <span class="site-state-item-count">83</span>
                    <span class="site-state-item-name">日志</span>
                  </a>
                </div>
              

              
                
                
                <div class="site-state-item site-state-categories">
                  <a href="/categories/index.html">
                    
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                    <span class="site-state-item-count">6</span>
                    <span class="site-state-item-name">分类</span>
                  </a>
                </div>
              

              
                
                
                <div class="site-state-item site-state-tags">
                  <a href="/tags/index.html">
                    
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                      
                    
                    <span class="site-state-item-count">124</span>
                    <span class="site-state-item-name">标签</span>
                  </a>
                </div>
              
            </nav>
          

          

          
            <div class="links-of-author motion-element">
              
                <span class="links-of-author-item">
                  <a href="https://github.com/vector4wang" target="_blank" title="GitHub" rel="external nofollow"><i class="fa fa-fw fa-github"></i>GitHub</a>
                  
                </span>
              
                <span class="links-of-author-item">
                  <a href="mailto:vector4wang@qq.com" target="_blank" title="E-Mail" rel="external nofollow"><i class="fa fa-fw fa-envelope"></i>E-Mail</a>
                  
                </span>
              
                <span class="links-of-author-item">
                  <a href="https://www.jianshu.com/u/223a1314e818" target="_blank" title="简书" rel="external nofollow"><i class="fa fa-fw fa-book"></i>简书</a>
                  
                </span>
              
                <span class="links-of-author-item">
                  <a href="http://blog.csdn.net/qqhjqs?viewmode=contents" target="_blank" title="CSDN" rel="external nofollow"><i class="fa fa-fw fa-crosshairs"></i>CSDN</a>
                  
                </span>
              
                <span class="links-of-author-item">
                  <a href="https://twitter.com/BMHJQS" target="_blank" title="Twitter" rel="external nofollow"><i class="fa fa-fw fa-twitter"></i>Twitter</a>
                  
                </span>
              
                <span class="links-of-author-item">
                  <a href="https://www.facebook.com/" target="_blank" title="FB Page" rel="external nofollow"><i class="fa fa-fw fa-facebook-official"></i>FB Page</a>
                  
                </span>
              
            </div>
          

          
          

          
          

          
            
          
          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#缓存"><span class="nav-number">1.</span> <span class="nav-text">缓存</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#对象的初始化"><span class="nav-number">2.</span> <span class="nav-text">对象的初始化</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#对象之间的比较"><span class="nav-number">3.</span> <span class="nav-text">对象之间的比较</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#"><span class="nav-number">3.1.</span> <span class="nav-text">==</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#equals"><span class="nav-number">3.2.</span> <span class="nav-text">equals</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#答案分析"><span class="nav-number">4.</span> <span class="nav-text">答案分析</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#扩展"><span class="nav-number">5.</span> <span class="nav-text">扩展</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#附加题"><span class="nav-number">6.</span> <span class="nav-text">附加题</span></a></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      
        <div class="back-to-top">
          <i class="fa fa-arrow-up"></i>
          
            <span id="scrollpercent"><span>0</span>%</span>
          
        </div>
      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<div class="copyright">&copy; <span itemprop="copyrightYear">2020</span>
  <span class="with-love" id="animate">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">wangxc</span>

  

  
</div>


  


<div class="powered-by">
<i class="fa fa-user-md"></i><span id="busuanzi_container_site_pv">
  本站访客数:<span id="busuanzi_value_site_uv"></span>
</span>
</div>


  <div class="powered-by">由 <a class="theme-link" target="_blank" rel="external nofollow" href="https://hexo.io">Hexo</a> 强力驱动 v3.8.0</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" rel="external nofollow" href="https://theme-next.org">NexT.Mist</a> v6.3.0</div>




        








        
      </div>
    </footer>

    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>


























  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=6.3.0"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=6.3.0"></script>



  
  

  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=6.3.0"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=6.3.0"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=6.3.0"></script>



  



	





  





  








  <script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
  
  
  <script src="//unpkg.com/valine/dist/Valine.min.js"></script>
  
  <script type="text/javascript">
    var GUEST = ['nick','mail','link'];
    var guest = 'nick,mail,link';
    guest = guest.split(',').filter(function (item) {
      return GUEST.indexOf(item)>-1;
    });
    new Valine({
        el: '#comments' ,
        verify: false,
        notify: false,
        appId: 'YdGFHBfuDwObik8qwCeRAWgr-gzGzoHsz',
        appKey: 'oFpbJwmMQf98DfFDUlzE5Fai',
        placeholder: 'Just go go',
        avatar:'mm',
        guest_info:guest,
        pageSize:'10' || 10,
    });
  </script>



  





  

  

  

  

  
  

  

  

  

  

  

</body>
</html>
